#ifndef __OS_SAL_H
#define __OS_SAL_H

#include "sdkconfig.h"
#include <stdint.h>

#if (CONFIG_OS_ENABLE == 1)

#if defined(CONFIG_OS_TYPE_FREERTOS)
#include "FreeRTOSConfig.h"
#if (configUSE_16_BIT_TICKS == 1)
#define OS_WAIT_MAX 0xffffUL
#else
#define OS_WAIT_MAX 0xffffffffUL
#endif
#define OS_NAME_SIZE configMAX_TASK_NAME_LEN //任务名长度

#else
#error "CONFIG_OS_TYPE not support!"
#endif

#endif // CONFIG_OS_ENABLE

typedef void (*os_task_t)(void *);
typedef void *os_task_handle_t;
typedef void *os_mutex_handle_t;
typedef void *os_sem_handle_t;
typedef void *os_queue_handle_t;
typedef void *os_event_handle_t;
typedef void *os_timer_handle_t;

typedef enum
{
    OS_STA_SUCCESS = 0,
    OS_STA_ERROR,
    OS_STA_TIMEOUT,
} os_status_t;

typedef enum
{
    os_false = 0,
    os_true,
} os_bool_t;

typedef struct
{
    os_task_handle_t task_handle;   //任务句柄
    char name[OS_NAME_SIZE];        //任务名
    char status;                    //任务状态
    uint32_t prio;                  //任务优先级
    uint32_t free_stk;              //剩余栈
    uint32_t id;                    //任务序号
    int32_t run_time;               //总运行时间
    int32_t usage;                  //使用率
} os_task_status_t;

/** exprot func **/

/* os task */
os_status_t os_task_create(void (*task)(void *param), void *param, const char *name, uint32_t stk_size, uint32_t prio, os_task_handle_t task_handle);
os_status_t os_task_delete(os_task_handle_t task_handle, void (*freefun)(void));
os_status_t os_task_suspend(os_task_handle_t handle);
os_status_t os_task_resume(os_task_handle_t handle);

/* os mutex */
os_mutex_handle_t os_mutex_create(void);
os_status_t os_mutex_delete(os_mutex_handle_t mutex);
os_status_t os_mutex_take(os_mutex_handle_t mutex, uint32_t waittime);
os_status_t os_mutex_release(os_mutex_handle_t mutex);

/* os sem */
os_sem_handle_t os_sem_binary_create(void);
os_sem_handle_t os_sem_count_create(uint32_t def, uint32_t max);
os_status_t os_sem_count_get_count(os_sem_handle_t sem, uint32_t *cnt);
os_status_t os_sem_delete(os_sem_handle_t sem);
os_status_t os_sem_take(os_sem_handle_t sem, uint32_t waittime);
os_status_t os_sem_release(os_sem_handle_t sem);

/* os queue */
os_queue_handle_t os_queue_create(uint32_t items, uint32_t size);
os_status_t os_queue_delete(os_queue_handle_t queue);
os_status_t os_queue_send(os_queue_handle_t queue, void *msg, uint32_t waittime);
os_status_t os_queue_receive(os_queue_handle_t queue, void *msg, uint32_t waittime);
os_status_t os_queue_reset(os_queue_handle_t queue);

/* os event */
os_event_handle_t os_event_create(void);
os_status_t os_event_delete(os_event_handle_t event);
os_status_t os_event_set_bits(os_event_handle_t event, uint32_t *value, uint32_t bits);
os_status_t os_event_wait_bits(os_event_handle_t event, uint32_t *value, uint32_t bits, uint8_t flag_clear_exit, uint8_t flag_wait_all_bits, uint32_t waittime);
os_status_t os_event_get_bits(os_event_handle_t event, uint32_t *value);
os_status_t os_event_clear_bits(os_event_handle_t event, uint32_t *value, uint32_t bits);

/* os timer */
os_timer_handle_t os_timer_create(const char *name, void (*func)(os_timer_handle_t xtimer), uint32_t ticks, os_bool_t reload, void *id);
os_status_t os_timer_delete(os_timer_handle_t timer, uint32_t waittime);
os_status_t os_timer_start(os_timer_handle_t timer, uint32_t waittime);
os_status_t os_timer_stop(os_timer_handle_t timer, uint32_t waittime);
os_status_t os_timer_change(os_timer_handle_t timer, uint32_t ticks, uint32_t waittime);

/* other */
void os_scheduler_start(void);
void os_scheduler_end(void);
void os_critical_enter(void);
void os_critical_exit(void);
void os_delay(uint32_t ticks);
void os_delay_ms(uint32_t ms);
void os_delay_unit(uint32_t ticks);
const char *os_get_name(void);
const char *os_get_version(void);
uint32_t os_get_heap_total_size(void);
uint32_t os_get_heap_free_size(void);
uint32_t os_get_task_nums(void);
os_status_t os_get_task_status(os_task_status_t **task_sta);
void os_systick_handler(void);
void *os_mem_malloc(uint32_t size);
void os_mem_free(void *ptr);

#endif // !__OS_SAL_H
